package main

import (
	"bufio"
	"fmt"
	"log"
	"math/rand"
	"os"
	"os/exec"
	"strings"
	"sync"
	"time"
)

type Storage struct {
	baseName     string
	baseNum      int
	baseMap      map[string]string
	fileNameMap  map[string]int
	fileNameChan chan string
	baseChan     chan string
	Mutex        sync.Mutex
}

func InitStorage() *Storage {

	return &Storage{

		baseMap:      make(map[string]string),
		fileNameMap:  make(map[string]int),
		baseChan:     make(chan string, 100000),
		fileNameChan: make(chan string, 1000000),
	}

}

type CameraInfo struct {
	ID  string // 摄像头ID (如 "cam001")
	URL string // RTSP地址 (如 "rtsp://192.168.1.10:554/stream1")
}

// ReadCameraFile 读取文件并返回解析后的摄像头信息列表,生成100天内的文件名
func (s *Storage) ReadCameraFile(filename string) ([]CameraInfo, error) {
	// 打开文件
	file, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	var cameras []CameraInfo
	scanner := bufio.NewScanner(file)

	// 逐行扫描文件
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line == "" {
			continue // 跳过空行
		}
		log.Println("文件内容", line)

		// 按竖线分割字段
		parts := strings.Split(line, "|")
		if len(parts) < 3 {
			continue // 跳过无效行（字段不足）
		}
		s.fileNameChan <- line

		// 开始生成100天内数据的文件名
		for i := 0; i < 2400; i++ {
			t1 := time.Now().Add(time.Duration(i) * time.Hour)
			t2 := t1.Format("2006-01-02-15") + "-00-00"
			str1 := parts[0] + "-" + t2 + ".mp4"
			s.fileNameMap[str1] = 0
			log.Println("生成文件名", str1)
		}

		// 提取摄像头ID和URL（忽略末尾空字段）
		cameras = append(cameras, CameraInfo{
			ID:  parts[0],
			URL: parts[1],
		})
	}

	if err := scanner.Err(); err != nil {
		return nil, err
	}
	return cameras, nil
}

// 通过管道发送任务
func (s *Storage) SendTask() {
	for {

		data := <-s.fileNameChan
		time.Sleep(1e7)
		arrayLine := strings.Split(data, "|")
		if len(arrayLine) != 3 {

			fmt.Println(time.Now(), data, "数据参数不对")
			continue
		}
		log.Println("收到消息", data)
		// 开始运行任务
		go s.RunTask(data)

	}
}

// 运行任务
func (s *Storage) RunTask(line string) {
	for {
		time.Sleep(3e8)
		// fmt.Println(time.Now(),"开始准备获取码流数据")
		str1 := time.Now().Format("04-05")
		parts := strings.Split(line, "|")
		//0分0秒开始获取数据
		if str1 == "00-00" {
			t1 := time.Now().Format("2006-01-02-15") + "-00-00"
			fileName := parts[0] + "-" + t1 + ".mp4"
			fileUrl := parts[1]
			//     fmt.Println(time.Now(), "需要生成的文件", fileName)
			s.Mutex.Lock()
			v := s.fileNameMap[fileName]
			if v == 0 {
				fmt.Println(time.Now(), "开始准备数据", fileName, fileUrl, v)
				// 运行shell
				go s.RunFFmpegSegmentCommand(fileUrl, "data/"+fileName)
				// 更新数据
				s.fileNameMap[fileName] = int(time.Now().Unix())
			}
			s.Mutex.Unlock()
		}
	}

}

// RunScript 执行一个名为 的脚本

func (s *Storage) RunFFmpegSegmentCommand(fileUrl, fileName string) {
	// 构建FFmpeg命令
	r := rand.New(rand.NewSource(time.Now().UnixNano()))

	// 生成0-2000毫秒的随机时长
	duration := time.Duration(r.Intn(2001)) * time.Millisecond

	// 执行等待
	time.Sleep(duration)
	cmd := exec.Command(
		"ffmpeg",
		"-rtsp_transport", "tcp",
		"-stimeout", "5000000",
		"-i", fileUrl,
		"-c:v", "copy", // 视频流直接复制
		"-c:a", "aac", // 音频流转码为AAC
		"-b:a", "128k", // 设置音频比特率

		"-t", "3600",
		fileName,
	)

	// 启动命令
	startTime := time.Now()
	if err := cmd.Start(); err != nil {
		fmt.Errorf("启动FFmpeg失败: %v", err)
		s.Mutex.Lock()
		s.fileNameMap[fileName] = -1
		s.Mutex.Unlock()
	}

	fmt.Println(time.Now(), "开始启动保存码流数据")

	// 等待命令完成
	if err := cmd.Wait(); err != nil {
		fmt.Errorf("FFmpeg执行失败: %v, 执行时间: %v", err, time.Since(startTime))
		s.Mutex.Lock()
		s.fileNameMap[fileName] = -1
		s.Mutex.Unlock()

	} else {

		s.Mutex.Lock()
		s.fileNameMap[fileName] = 1
		s.Mutex.Unlock()

	}

}

func main() {
	Storage := InitStorage()
	go Storage.SendTask()
	log.Println("开始读配置文件")
	_, err := Storage.ReadCameraFile("conf/cameras.txt")
	if err != nil {
		panic(err)
	}
	log.Println("开始等待数据")
	for {
		time.Sleep(10e9)
		fmt.Println(time.Now())
	}
}
